package com.tunnel.home.rest;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.axe.annotation.ioc.Autowired;
import org.axe.annotation.ioc.Controller;
import org.axe.annotation.mvc.FilterFuckOff;
import org.axe.annotation.mvc.Request;
import org.axe.annotation.mvc.RequestParam;
import org.axe.constant.RequestMethod;
import org.axe.exception.RestException;
import org.axe.helper.base.MailHelper;
import org.axe.util.MD5Util;
import org.axe.util.StringUtil;

import com.tunnel.home.common.Constant;
import com.tunnel.home.common.RedisUtil;
import com.tunnel.home.dao.UserDao;
import com.tunnel.home.entity.User;
import com.tunnel.home.server.UserService;

@Controller(basePath="/user",desc="用户")
public class UserRest {
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserService userService;

	@FilterFuckOff
	@Request(path = "/forget_password", method = RequestMethod.POST, desc = "忘记密码")
	public void forget_password(
			@RequestParam(name="email",required=true,desc="邮箱")String email){
		//防止重复提交
		if(StringUtil.isNotEmpty(RedisUtil.getString(Constant.REQUEST_LIMIT+email))){
			return;
		}
		RedisUtil.setKeyValue(Constant.REQUEST_LIMIT+email,"",1);//1秒过期
		
		//如果注册用户10分钟内如果发送过注册邮件，提示过会儿再来
		if(StringUtil.isNotEmpty(RedisUtil.getString(Constant.EMAIL_SEND_LIMIT+email+"#forget_password"))){
			throw new RestException("之前的验证邮件已经发送，如果还没收到，请耐心等待一会儿，或者请稍后再试一下...");
		}
		
		User user = userDao.getUser(email);
		if(user == null){
			throw new RestException("此邮箱未注册");
		}
		
		String code = StringUtil.getRandomString(16);
		RedisUtil.setKeyValue(Constant.FORGET_PASSWORD_CHECK_CODE+code, user.getId().toString(), Constant.SECONDS_OF_24_HOURS);//24小时
		
		StringBuilder buf = new StringBuilder();
		buf.append("Tunnel重置密码，请点击下面的链接完成验证（24小时内有效）：<br/>");
		buf.append("<a href=\"https://www.tunnel.cool/user/forget_password_check?code="+code+"\">点我完成验证</a>");
		String content = buf.toString();
		boolean success = MailHelper.sendMail(email, "Tunnel 重置密码", content);
		if(success){
			RedisUtil.setKeyValue(Constant.EMAIL_SEND_LIMIT+email+"#forget_password", "ok", Constant.SECONDS_OF_10_MINUTES);
		}
	}
	
	@FilterFuckOff
	@Request(path = "/forget_password_check", method = RequestMethod.GET, desc = "重置密码验证")
	public String forget_password_check(
			@RequestParam(name="code",required=true,desc="验证码")String code){
		String userIdStr = RedisUtil.getAndDelString(Constant.FORGET_PASSWORD_CHECK_CODE+code);
		if(StringUtil.isEmpty(userIdStr)){
			return "激活链接已失效，请重新注册";
		}
		
		RedisUtil.setKeyValue(Constant.RESET_PASSWORD+userIdStr, "ok", Constant.SECONDS_OF_10_MINUTES);//10分钟
		return "验证成功，请在10分钟内，使用新密码登录即可。";
	}
	
	@FilterFuckOff
	@Request(path = "/login", method = RequestMethod.POST, desc = "登录")
	public String login(
			@RequestParam(name="email",required=true,desc="邮箱")String email,
			@RequestParam(name="password",required=true,desc="密码")String password){
		User user;
		try {
			user = userService.checkUserAuth(email, password);
		} catch (Exception e) {
			throw new RestException(e.getMessage());
		}
		
		//生成新的token
		String token = MD5Util.getMD5Code(user.getId()+StringUtil.getRandomString(6));//每个用户就肯定都不一样了
		userDao.setToken(user.getId(), token);
		
		//缓存
		
		return token;
		
	}
	
	@FilterFuckOff
	@Request(path = "/register", method = RequestMethod.POST, desc = "注册")
	public void register(
			@RequestParam(name="email",required=true,desc="邮箱")String email,
			@RequestParam(name="password",required=true,desc="密码")String password
			) {
		if(StringUtil.isNotEmpty(RedisUtil.getString(Constant.REQUEST_LIMIT+email))){
			return;
		}
		RedisUtil.setKeyValue(Constant.REQUEST_LIMIT+email,"",1);//1秒过期
		
		User user = userDao.getUser(email);
		if(user != null && user.getEmailStatus() == 1){
			throw new RestException("此邮箱账号已注册，请直接登录");
		}
		
		//如果注册用户10分钟内如果发送过注册邮件，提示过会儿再来
		if(user != null && StringUtil.isNotEmpty(RedisUtil.getString(Constant.EMAIL_SEND_LIMIT+email+"#register"))){
			throw new RestException("之前的注册邮件已经发送，如果还没收到，请耐心等待一会儿，或者请稍后再试一下...");
		}

		//如果已经提交过了
		if(user == null){
			user = new User();
		}
		user.setEmail(email);
		user.setEmailStatus(0);//待激活
		user.setSalt(StringUtil.getRandomString(6));
		String code = MD5Util.getMD5Code(password);
		password = MD5Util.getMD5Code(code+user.getSalt());
		user.setPassword(password);
		user.setCreateTime(new Date());
		user=userDao.saveEntity(user);
		
		
		RedisUtil.setKeyValue(Constant.REGISTER_ACTIVE_CODE+code, "ok", Constant.SECONDS_OF_24_HOURS);//24小时
		StringBuilder buf = new StringBuilder();
		buf.append("欢迎使用Tunnel，请点击下面的链接完成注册激活（24小时内有效）：<br/>");
		buf.append("<a href=\"https://www.tunnel.cool/user/activation?id="+user.getId()+"&code="+code+"\">点我完成验证</a>");
		String content = buf.toString();
		boolean success = MailHelper.sendMail(email, "Tunnel 注册激活", content);
		if(success){
			RedisUtil.setKeyValue(Constant.EMAIL_SEND_LIMIT+email+"#register", "ok", Constant.SECONDS_OF_10_MINUTES);
		}
	}
	
	@FilterFuckOff
	@Request(path = "/activation", method = RequestMethod.GET, desc = "激活")
	public String activation(
			@RequestParam(name="id",required=true,desc="用户账号id")Long id,
			@RequestParam(name="code",required=true,desc="激活码")String code
			) {
		String check = RedisUtil.getString(Constant.REGISTER_ACTIVE_CODE+code);
		if(StringUtil.isEmpty(check)){
			return "激活链接已失效，请重新注册";
		}
		
		User user = userDao.getUser(id);
		if(user == null){
			return "激活失败";
		}
		if(user.getEmailStatus() == 1){
			return "邮箱已激活，请直接登录";
		}
		//code其实是用户真实密码的md5
		String password = MD5Util.getMD5Code(code+user.getSalt());
		if(!password.equals(user.getPassword())){
			return "激活失败";
		}
		
		userDao.activeEmail(id);
		return "激活成功";
	}
	
	
	@Request(path="/info",method=RequestMethod.GET,desc="用户信息")
	public Map<String,String> info(User user){
		Map<String,String> map = new HashMap<>();
		map.put("name", user.getEmail());
		map.put("status", String.valueOf(user.getStatus()));
		if(user.getExpireTime() == null){
			map.put("expire", "非会员");
		}else{
			long leavesTime = user.getExpireTime().getTime()-System.currentTimeMillis();
			long days = leavesTime>0?leavesTime/86400000+1:0;
			if(days > 0){
				map.put("expire", "会员剩余"+days+"天");
			}else{
				map.put("expire", "会员已过期");
			}
		}
		return map;
	}

}
